home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
011-020
/
amok19
/
trackdisksupport
/
trackdisksupport.mod
< prev
next >
Wrap
Text File
|
1993-11-04
|
11KB
|
394 lines
(**********************************************************************
:Program. TrackDiskSupport.mod
:Contents. Support to access trackdisk sectors
:Author. Fridtjof Siebert [fbs]
:Address. [fbs] Nobileweg 67, D7000 Stuttgart 40
:Phone. [fbs] (0)711/822509
:Author. Nicolas Benezan [bne]
:Address. [bne] Postwiesenstr. 2, D7000 Stuttgart 60
:Phone. [bne] 0711/333679
:Copyright. Public Domain, no commercial use !!!
:Language. Modula-2
:Translator. M2Amiga A+L V3.2d
:Imports. DosSupport1.3, TaskMemory [bne]
:History. V1.0 [fbs] 5.Dez.1988
:History. V1.1 [bne] 12.May.1989 (adapted m2c V3.2d)
:History. V2.0 [bne] 13.May.1989 (+other drivetypes, DHx: etc.)
:Remark. Hi Fridtjof, my V2.0 code is 18% smaller! [bne]
:History. V2.1 [bne] 14.May.1989 (+ InhibitDrive)
**********************************************************************)
IMPLEMENTATION MODULE TrackDiskSupport;
FROM Arts IMPORT Assert, TermProcedure, DetectCtrlC;
FROM Dos IMPORT DeviceListType, ProcessPtr, StandardPacket,
inhibit;
FROM DosSupport IMPORT BPTRtoADR, BSTRtoStr, GetDevList, StartupInfoPtr,
DiskInfoPtr, DeviceListPtr;
FROM Exec IMPORT DoIO, OpenDevice, CloseDevice, MsgPortPtr, Byte,
FindTask, PutMsg, WaitPort, GetMsg, message;
FROM ExecSupport IMPORT CreatePort, DeletePort, CreateExtIO, DeleteExtIO;
FROM SYSTEM IMPORT ADR, LONGSET, ADDRESS, BITSET, BPTR, CAST;
FROM TaskMemory IMPORT Allocate, Deallocate;
FROM TrackDisk IMPORT motor, seek, changeNum, changeState, extClear,
protStatus, getDriveType, getNumTracks,
extRead, extWrite, extUpdate, extFormat,
trackDiskName, IOTrackDisk, IOTrackDiskPtr,
badDriveType, noMem;
TYPE
DiskUnit=POINTER TO DiskUnitRec;
DiskUnitRec=RECORD
link:DiskUnit;
replyPort:MsgPortPtr;
reqBlock:IOTrackDiskPtr;
info:DeviceInfo;
END;
VAR
OpenList:DiskUnit;
(**)
(* Scan Dos device list and open the device *)
(**)
PROCEDURE OpenDiskDevice( DeviceName: ARRAY OF CHAR;
VAR Unit: DiskUnit): Byte;
VAR
Error: Byte;
DeviceNode:DeviceListPtr;
PROCEDURE ScanDeviceList():BOOLEAN;
CONST
nul=CHR(0);
VAR
DevName:Name;
Pos:INTEGER;
BEGIN
DeviceNode:=GetDevList();
LOOP
IF DeviceNode=NIL THEN
RETURN FALSE
END;
WITH DeviceNode^ DO
IF type=device THEN
BSTRtoStr(name,DevName);
Pos:=0;
WHILE DevName[Pos]=DeviceName[Pos] DO
IF (DevName[Pos]=nul) AND (DeviceName[Pos]=nul) THEN
RETURN TRUE
END;
INC(Pos);
END;
END;
DeviceNode:=BPTRtoADR(next);
END;
END;
END ScanDeviceList;
PROCEDURE ReadDevInfo():BOOLEAN;
VAR
Startup:StartupInfoPtr;
BEGIN
WITH Unit^.info DO
handler:=DeviceNode^.task;
Startup:=BPTRtoADR(CAST(BPTR,DeviceNode^.startup));
IF Startup=NIL THEN
RETURN FALSE
END;
WITH Startup^ DO
BSTRtoStr(execName,devName);
devUnit :=unit;
devFlags:=flags;
disk:=BPTRtoADR(diskInfo);
END;
IF (disk=NIL) OR (disk^.length<11) THEN
RETURN FALSE
END;
WITH disk^ DO
blockLen :=blockSize*4; (* longword = 4 bytes *)
trackLen :=blockLen*numSecs;
cylinderLen:=trackLen*surfaces;
numBlocks :=(highCyl-lowCyl+1)*surfaces*numSecs;
offset :=lowCyl*cylinderLen; (* partition origin *)
END;
END;
RETURN TRUE;
END ReadDevInfo;
BEGIN
Error:=noMem;
DetectCtrlC(FALSE);
TrackDiskAllocProc(Unit,SIZE(Unit^));
IF Unit#NIL THEN
Error:=badDriveType;
IF ScanDeviceList() AND ReadDevInfo() THEN
WITH Unit^ DO
replyPort:=CreatePort(NIL,0);
IF replyPort#NIL THEN
reqBlock:=CreateExtIO(replyPort,SIZE(IOTrackDisk));
IF reqBlock#NIL THEN
OpenDevice(ADR(info.devName),info.devUnit,reqBlock,info.devFlags);
Error:=reqBlock^.req.error;
IF Error=0 THEN
link:=OpenList; (* add node *)
OpenList:=Unit;
DetectCtrlC(TRUE);
RETURN 0;
END;
DeleteExtIO(reqBlock);
END;
DeletePort(replyPort);
END;
END; (* WITH Unit^ *)
END;
TrackDiskDeallocProc(Unit);
END;
DetectCtrlC(TRUE);
RETURN Error;
END OpenDiskDevice;
PROCEDURE CloseDiskDevice(Unit: DiskUnit);
VAR
Prev,Node:DiskUnit;
BEGIN
Prev:=ADR(OpenList);
Node:=OpenList;
WHILE Node#Unit DO
Prev:=Node;
Node:=Node^.link;
Assert(Node#NIL,ADR("CloseDiskDevice: no unit"));
END;
WITH Unit^ DO
Prev^.link:=link; (* remove node *)
CloseDevice(reqBlock);
DeleteExtIO(reqBlock);
DeletePort(replyPort);
END;
TrackDiskDeallocProc(Unit);
END CloseDiskDevice;
PROCEDURE GetDeviceInfo( Unit: DiskUnit;
VAR Info: DeviceInfo);
BEGIN
Info:=Unit^.info;
END GetDeviceInfo;
PROCEDURE DoRequest(ReqBlock:IOTrackDiskPtr;
Command:CARDINAL);
BEGIN
ReqBlock^.req.command:=Command;
DetectCtrlC(FALSE);
DoIO(ReqBlock);
DetectCtrlC(TRUE);
END DoRequest;
PROCEDURE GetDiskChange(Unit: DiskUnit): LONGINT;
BEGIN
WITH Unit^ DO
DoRequest(reqBlock,changeNum);
RETURN reqBlock^.req.actual;
END;
END GetDiskChange;
PROCEDURE ChangeState(Unit: DiskUnit): BOOLEAN;
BEGIN
WITH Unit^ DO
DoRequest(reqBlock,changeState);
RETURN reqBlock^.req.actual=0;
END;
END ChangeState;
PROCEDURE ProtStatus(Unit: DiskUnit): BOOLEAN;
BEGIN
WITH Unit^ DO
DoRequest(reqBlock,protStatus);
RETURN reqBlock^.req.actual=0;
END;
END ProtStatus;
PROCEDURE Motor(Unit: DiskUnit; On: BOOLEAN): BOOLEAN;
BEGIN
WITH Unit^ DO
IF On THEN
reqBlock^.req.length:=1;
ELSE
reqBlock^.req.length:=0;
END;
DoRequest(reqBlock,motor);
RETURN reqBlock^.req.actual=1;
END;
END Motor;
PROCEDURE Seek(Unit: DiskUnit; BlockNum: LONGINT): Byte;
BEGIN
WITH Unit^ DO
reqBlock^.req.offset:=BlockNum*info.blockLen + info.offset;
DoRequest(reqBlock,seek);
RETURN reqBlock^.req.error;
END;
END Seek;
PROCEDURE ReadBlock(Unit: DiskUnit;
Block: LONGINT;
NumBlocks: CARDINAL;
Buffer: ADDRESS;
ChangeCnt: LONGINT): Byte;
BEGIN
WITH Unit^ DO
WITH reqBlock^ DO
req.data :=Buffer;
req.length:=LONGINT(NumBlocks)*info.blockLen;
req.offset:=Block*info.blockLen + info.offset;
count :=ChangeCnt;
secLabel :=NIL;
END;
DoRequest(reqBlock,extRead);
RETURN reqBlock^.req.error;
END;
END ReadBlock;
PROCEDURE WriteBlock(Unit: DiskUnit;
Block: LONGINT;
NumBlocks: CARDINAL;
Buffer: ADDRESS;
ChangeCnt: LONGINT): Byte;
BEGIN
WITH Unit^ DO
WITH reqBlock^ DO
req.data :=Buffer;
req.length:=LONGINT(NumBlocks)*info.blockLen;
req.offset:=Block*info.blockLen + info.offset;
count :=ChangeCnt;
secLabel :=NIL;
END;
DoRequest(reqBlock,extWrite);
RETURN reqBlock^.req.error;
END;
END WriteBlock;
PROCEDURE Update(Unit: DiskUnit;
ChangeCnt: LONGINT): Byte;
BEGIN
WITH Unit^ DO
reqBlock^.count:=ChangeCnt;
DoRequest(reqBlock,extUpdate);
RETURN reqBlock^.req.error;
END;
END Update;
PROCEDURE FormatTrack(Unit: DiskUnit;
Cylinder: CARDINAL;
Head: CARDINAL;
Buffer: ADDRESS;
ChangeCnt: LONGINT): Byte;
VAR
TrackSize:LONGINT;
BEGIN
WITH Unit^ DO
WITH reqBlock^ DO
req.length:=info.trackLen;
req.offset:=LONGINT(Head)*info.trackLen +
LONGINT(Cylinder)*info.cylinderLen +
info.offset;
req.data :=Buffer;
count :=ChangeCnt;
END;
DoRequest(reqBlock,extFormat);
RETURN reqBlock^.req.error;
END;
END FormatTrack;
PROCEDURE Clear(Unit: DiskUnit): Byte;
BEGIN
WITH Unit^ DO
DoRequest(reqBlock,extClear);
RETURN reqBlock^.req.error;
END;
END Clear;
PROCEDURE GetDriveType(Unit: DiskUnit): LONGINT;
BEGIN
WITH Unit^ DO
DoRequest(reqBlock,getDriveType);
RETURN reqBlock^.req.actual;
END;
END GetDriveType;
PROCEDURE GetNumTracks(Unit: DiskUnit): LONGINT;
BEGIN
WITH Unit^ DO
DoRequest(reqBlock,getNumTracks);
RETURN reqBlock^.req.actual;
END;
END GetNumTracks;
PROCEDURE BlockNumber(Unit: DiskUnit;
Cylinder, Sector, Head: LONGINT): LONGINT;
BEGIN
WITH Unit^.info DO
RETURN (Cylinder * cylinderLen + Head * trackLen)/blockLen + Sector;
END;
END BlockNumber;
PROCEDURE InhibitDrive(Unit: DiskUnit;
Inhibit: BOOLEAN): BOOLEAN;
VAR
Packet:POINTER TO StandardPacket;
ThisProcess:ProcessPtr;
ReplyPort:MsgPortPtr;
Ok:BOOLEAN;
BEGIN
ThisProcess:=CAST(ProcessPtr,FindTask(NIL));
ReplyPort:=ADR(ThisProcess^.msgPort);
TrackDiskAllocProc(Packet,SIZE(Packet^));
IF Packet#NIL THEN
WITH Packet^ DO
WITH msg DO
node.type:=message;
node.pri :=0;
node.name:=ADR(pkt);
replyPort:=ReplyPort;
length :=SIZE(Packet^);
END;
WITH pkt DO
link:=ADR(msg);
port:=ReplyPort;
type:=inhibit;
IF Inhibit THEN
arg1:=1;
ELSE
arg1:=0;
END;
END;
END;
PutMsg(Unit^.info.handler,Packet);
WaitPort(ReplyPort);
Packet:=GetMsg(ReplyPort);
WITH Packet^.pkt DO
Ok:=res1#0;
ThisProcess^.result2:=res2;
END;
TrackDiskDeallocProc(Packet);
END;
RETURN Ok;
END InhibitDrive;
PROCEDURE CleanUp;
VAR
Next:DiskUnit;
BEGIN
WHILE OpenList#NIL DO
Next:=OpenList^.link;
CloseDiskDevice(OpenList);
OpenList:=Next;
END;
END CleanUp;
BEGIN
OpenList:=NIL;
TrackDiskAllocProc:=Allocate;
TrackDiskDeallocProc:=Deallocate;
TermProcedure(CleanUp);
END TrackDiskSupport.